package com.sky.aspect;

/**
 * @author 丹辰
 * @version 1.0
 * @date 2024/10/26 15:43
 */

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 自定义切面，实现公共部分自动填充
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

 /**
  * 切入点
  */
 @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
 public void  autoFillPointCut(){

 }

 /**
  * 前置通知，在通知中进行公共字段的赋值
  */
 @Before("autoFillPointCut()")
 public void autofill(JoinPoint joinPoint){
log.info("开始进行公共字段的自动填充...");

  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
  OperationType operationType = autoFill.value();

  Object[] args = joinPoint.getArgs();
  if (args == null||args.length==0) {
      return;
  }


  Object entity = args[0];

  LocalDateTime now = LocalDateTime.now();
  Long currentId = BaseContext.getCurrentId();

  if (operationType == operationType.INSERT) {
   try {
    Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
    Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
    Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
    Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
    //通过发射为对象赋值
setCreateTime.invoke(entity,now);
setCreateUser.invoke(entity,currentId);
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else if (operationType == operationType.UPDATE) {
   try {
    Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
    Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
    //通过发射为对象赋值
    setUpdateTime.invoke(entity,now);
    setUpdateUser.invoke(entity,currentId);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }

 }
}
